const add = (a, b, c, d) => a + b + c + d;

/* 多参函数的柯里化 */
function curryDemo() {
  const curry = (fn) => {
    return function cfn(...args) {
      /* 递归终止条件：参数凑齐 */
      if (args.length === fn.length) {
        return fn.apply(null, args);
      }

      return function (...b) {
        // 修改外层闭包中的参数列表长度 逐渐接近递归终止条件
        args = args.concat(b);
        return cfn(...args);
      };
    };
  };

  const cadd = curry(add);
  console.log(cadd(1, 2, 3, 4)); //10
  console.log(cadd(1, 2)(3)(4)); //10
}
// curryDemo();

function reduceDemo(){
    const arr = [1,2,3,4]
    arr.reduce(
        (pv,cv,index)=>{
            console.log(index,cv,pv);
            return cv + pv
        },
        100
    )
}
// reduceDemo()

/* 管道与组合 */
function pipeDemo() {
    const pipe = (...fns) => (v => fns.reduce(
        (pv,fn,index)=>fn(pv),
        v
    ))
    const compose = (...fns) => (v => fns.reverse().reduce(
        (pv,fn,index)=>fn(pv),
        v
    ))

  //求数值的长度
  const len = (n) => (n + "").length;
  //求n的平方
  const pow = (n) => n * n;
  // 求立方根
  const cubicRoot = (n) => Math.cbrt(n);

  // 从左往右处理
  console.log(pipe(len, pow, cubicRoot)(10)); //10的长度为2 平方后得4 开三方得1.x

  // 从右往左处理
  console.log(compose(len, pow, cubicRoot)(1000)); //1000立方根10 平方后100 长度3
}
// pipeDemo();

/* 同步函数的Promise化 */
async function promDemo() {
    function promisify(fn){
        return function(...args){
            return new Promise(
                (resolve,reject)=>{
                    try {
                        resolve(fn.apply(null,args))
                    } catch (err) {
                        reject(err)
                    }
                }
            )
        }
    }

    const add = (a, b, c, d) => {
        if(Math.random() > 0.7) {
            throw new Error("人品槽已空，请尽快充100块钱的人品")
        }
        return a + b + c + d
    }
    const pow = (a, b) => {
        if(Math.random() > 0.7) {
            throw new Error("人品槽已空，请尽快充100块钱的人品")
        }
        return Math.pow(a,b)
    }

    const padd = promisify(add)
    const ppow = promisify(pow)

    // padd(1,2,3,4).then(
    //     data => {
    //         console.log("data=",data)
    //         return ppow(data,2)
    //     }
    // )
    // .then(
    //     data => console.log("data=",data)
    // )
    // .catch(
    //     err => console.error("err=",err)
    // )

    try {
        let data = await padd(1,2,3,4)
        console.log("data=",data)
    
        data = await ppow(data,2)
        console.log("data=",data)
    } catch (err) {
        console.error("err=",err)
    }

}
promDemo()
